package com.zzh.webhook.service;

import com.zzh.webhook.config.GitlabConfig;
import com.zzh.webhook.config.ProjectConfig;
import com.zzh.webhook.utils.CommandExecutor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

@Slf4j
@Service
@RequiredArgsConstructor
public class GitService {
    
    private final CommandExecutor commandExecutor;
    private final ProjectConfig projectConfig;
    private final GitlabConfig gitlabConfig;
    
    // 硬编码的仓库地址和分支
    private static final String GIT_REPO_URL = "http://swq:00000000@118.31.16.213/wangchuyu/IMT_LIMS.git";
    private static final String GIT_BRANCH = "zzhnb";
    
    /**
     * 初始化或更新本地Git仓库
     */
    public void initOrUpdateRepository() throws IOException {
        String localPath = projectConfig.getGit().getLocalPath();
        
        File repoDir = new File(localPath);
        
        if (!repoDir.exists()) {
            // 如果本地仓库不存在，则克隆
            log.info("Local repository does not exist. Cloning from repository");
            // 设置环境变量强制Git显示进度
            String cloneCommand = String.format("git -c progress.display=full -c core.logallrefupdates=true clone -v --progress -b %s %s %s", 
                    GIT_BRANCH, GIT_REPO_URL, localPath);
            commandExecutor.execute(cloneCommand, null);
        } else {
            // 如果本地仓库已存在，则拉取最新代码
            log.info("Updating local repository at: {}", localPath);
            // 确保远程仓库设置正确
            String setRemoteCommand = String.format("git remote set-url origin %s", GIT_REPO_URL);
            commandExecutor.execute(setRemoteCommand, localPath);
            
            // 拉取所有分支，显示进度
            String fetchCommand = "git -c progress.display=full fetch --progress --all";
            commandExecutor.execute(fetchCommand, localPath);
        }
    }
    
    /**
     * 构建带有认证信息的Git URL
     */
    private String getGitUrlWithAuth() {
        String gitUrl = projectConfig.getGit().getUrl();
        
        try {
            URI uri = new URI(gitUrl);
            String scheme = uri.getScheme();
            String host = uri.getHost();
            int port = uri.getPort();
            String path = uri.getPath();
            
            // 如果配置了访问令牌，优先使用访问令牌
            if (gitlabConfig.getAuth().getAccessToken() != null && !gitlabConfig.getAuth().getAccessToken().isEmpty()) {
                return String.format("%s://oauth2:%s@%s%s%s",
                        scheme,
                        gitlabConfig.getAuth().getAccessToken(),
                        host,
                        port > 0 ? ":" + port : "",
                        path);
            }
            
            // 否则使用用户名和密码
            if (gitlabConfig.getAuth().getUsername() != null && !gitlabConfig.getAuth().getUsername().isEmpty()) {
                return String.format("%s://%s:%s@%s%s%s",
                        scheme,
                        gitlabConfig.getAuth().getUsername(),
                        gitlabConfig.getAuth().getPassword(),
                        host,
                        port > 0 ? ":" + port : "",
                        path);
            }
            
            // 如果没有配置认证信息，则使用原始URL
            return gitUrl;
        } catch (URISyntaxException e) {
            log.error("Invalid Git URL: {}", gitUrl, e);
            return gitUrl;
        }
    }
    
    /**
     * 屏蔽URL中的敏感信息，用于日志记录
     */
    private String maskCredentials(String url) {
        return url.replaceAll("://[^@]*@", "://***:***@");
    }
    
    /**
     * 切换到指定分支并拉取最新代码
     * 
     * @param branch 分支名称
     */
    public void checkoutAndPull(String branch) throws IOException {
        String localPath = projectConfig.getGit().getLocalPath();
        
        log.info("Checking out branch: {} in repository: {}", branch, localPath);
        
        // 切换到指定分支
        String checkoutCommand = String.format("git checkout %s", branch);
        commandExecutor.execute(checkoutCommand, localPath);
        
        // 拉取最新代码，指定远程仓库和分支，显示进度
        String pullCommand = String.format("git -c progress.display=full pull --progress origin %s", branch);
        commandExecutor.execute(pullCommand, localPath);
    }
    
    /**
     * 分析提交中修改的文件，确定受影响的模块
     * 
     * @param commitFiles 修改的文件列表
     * @return 受影响的模块列表
     */
    public boolean isCommonModuleChanged(Iterable<String> commitFiles) {
        for (String file : commitFiles) {
            for (String commonModule : projectConfig.getModules().getCommonModules()) {
                if (file.startsWith(commonModule + "/")) {
                    return true;
                }
            }
        }
        return false;
    }
    
    /**
     * 获取指定文件列表中受影响的模块
     * 
     * @param commitFiles 修改的文件列表
     * @return 受影响的模块列表
     */
    public java.util.Set<String> getAffectedModules(Iterable<String> commitFiles) {
        java.util.Set<String> affectedModules = new java.util.HashSet<>();
        
        for (String file : commitFiles) {
            for (String module : projectConfig.getModules().getAllModules()) {
                if (file.startsWith(module + "/")) {
                    affectedModules.add(module);
                    break;
                }
            }
        }
        
        return affectedModules;
    }
} 